/*
  Arduino.h - Main include file for the Arduino SDK
  Copyright (c) 2005-2013 Arduino Team.  All right reserved.

  This library is free software; you can redistribute it and/or
  modify it under the terms of the GNU Lesser General Public
  License as published by the Free Software Foundation; either
  version 2.1 of the License, or (at your option) any later version.

  This library is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  Lesser General Public License for more details.

  You should have received a copy of the GNU Lesser General Public
  License along with this library; if not, write to the Free Software
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
*/

#ifndef Arduino_h
#define Arduino_h

#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#include <stdint.h>
#include <math.h>

#include "Platform/platform.h"

#ifdef __cplusplus
extern "C" {
#endif

#define LOW                 0x0
#define HIGH                0x1

#define INPUT               0x0
#define OUTPUT              0x1
#define INPUT_PULLUP        0x2

#define PI                  3.1415926535897932384626433832795
#define HALF_PI             1.5707963267948966192313216916398
#define TWO_PI              6.283185307179586476925286766559
#define DEG_TO_RAD          0.017453292519943295769236907684886
#define RAD_TO_DEG          57.295779513082320876798154814105
#define EULER               2.718281828459045235360287471352

#define SERIAL              0x0
#define DISPLAY             0x1

#define LSBFIRST            0
#define MSBFIRST            1

#define CHANGE              1
#define FALLING             2
#define RISING              3


// undefine stdlib's abs if encountered
#ifdef abs
#undef abs
#endif

#define min(a,b)            ((a)<(b)?(a):(b))
#define max(a,b)            ((a)>(b)?(a):(b))
#define abs(x)              ((x)>0?(x):-(x))
#define constrain(amt,low,high)     ((amt)<(low)?(low):((amt)>(high)?(high):(amt)))
#define round(x)            ((x)>=0?(long)((x)+0.5):(long)((x)-0.5))
#define radians(deg)        ((deg)*DEG_TO_RAD)
#define degrees(rad)        ((rad)*RAD_TO_DEG)
#define sq(x)               ((x)*(x))

#define lowByte(w)          ((uint8_t) ((w) & 0xff))
#define highByte(w)         ((uint8_t) ((w) >> 8))

#define bit(b)              (1UL << (b))
#define bitRead(value,bit)  (((value) >> (bit)) & 0x01)
#define bitSet(value,bit)   ((value) |= (1UL << (bit)))
#define bitClear(value,bit) ((value) &= ~(1UL << (bit)))
#define bitToggle(value, bit)   ((value) ^= (1UL << (bit)))
#define bitWrite(value, bit, bitvalue) ((bitvalue) ? bitSet(value, bit) : bitClear(value, bit))


#define clockCyclesPerMicrosecond()     ( F_CPU / 1000000L )
#define clockCyclesToMicroseconds(a)    ( (a) / clockCyclesPerMicrosecond() )
#define microsecondsToClockCycles(a)    ( (a) * clockCyclesPerMicrosecond() )


#define NOT_A_PIN           0
#define NOT_A_PORT          0
#define NOT_AN_INTERRUPT    -1
#define NOT_ON_TIMER        0

// Mcu port define
#define interrupts()    sei()
#define noInterrupts()  cli()

#define delay(ms)                delay_ms(ms)
#define delayMicroseconds(us)    delay_us(us)

// avr-libc defines _NOP() since 1.6.2
#ifndef _NOP
#define _NOP() do { __asm__ volatile ("nop"); } while (0)
#endif


typedef bool          boolean;
typedef unsigned char byte;
typedef unsigned int  word;


void pinMode(uint32_t pin, uint32_t mode);
void digitalWrite(uint32_t pin, uint8_t val);
int digitalRead(uint32_t pin);
int analogRead(uint8_t pin);
void analogWrite(uint8_t pin, int val);
void analogReference(uint8_t mode);

uint32_t pulseIn(uint8_t pin, uint8_t state, uint32_t timeout);
uint32_t pulseInLong(uint8_t pin, uint8_t state, uint32_t timeout);

void shiftOut(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder, uint8_t val);
uint8_t shiftIn(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder);

void tone(uint8_t _pin, uint32_t frequency, uint32_t duration);
void noTone(uint8_t _pin);

// WMath prototypes
long map(long x, long in_min, long in_max, long out_min, long out_max);
void yield(void);


#ifdef __cplusplus
} // extern "C"
#endif

#ifdef __cplusplus
#   include "WString.h"
#   include "HardwareSerial.h"
#endif // __cplusplus


#endif
